#pragma once

#include "./base_type.h"

namespace lukv {


class list_t : public base_type {
public:
    list_t();
    list_t(const list_t &);
    list_t(list_t &&) noexcept;
public:
    ~list_t() noexcept override;
public:
    data_type get_type() override;
    std::pair<char, std::string> handle(const std::vector<std::string> &) override;
public:
    void lpush(const std::string &);
    void rpush(const std::string &);
    void lpop();
    void rpop();
    std::string lget();
    std::string rget();
private:
    std::list<std::string> _content;
};

list_t::list_t() = default;

list_t::list_t(const list_t & _l) {
    _content = _l._content;
}

list_t::list_t(list_t && _l) noexcept {
    _content = std::move(_l._content);
}

list_t::~list_t() noexcept = default;

data_type list_t::get_type() {
    return list;
}

std::pair<char, std::string> list_t::handle(const std::vector<std::string> & _cmds) {
    if (_cmds[0] != "list") {
        LOG_ERR(ERR_TYPE);
        return { -1, ERR_TYPE };
    }
    if (_cmds[1] == "get") {
        if (_cmds.size() < 4) {
            LOG_ERR(ERR_SYNTAX);
            return { -1, ERR_SYNTAX };
        }
        if (_cmds[3] == "left") return { 0, lget() };
        else if (_cmds[3] == "right") return { 0, rget() };
        else {
            LOG_ERR(ERR_SYNTAX);
            return { -1, ERR_SYNTAX };
        }
    }
    else if (_cmds[1] == "set") {
        if (_cmds.size() < 4) {
            LOG_ERR(ERR_SYNTAX);
            return { -1, ERR_SYNTAX };
        }
        if (_cmds[3] == "lpop") lpop();
        else if (_cmds[3] == "rpop") rpop();
        else if (_cmds[3] == "lpush") {
            if (_cmds.size() < 5) {
                LOG_ERR(ERR_SYNTAX);
                return { -1, ERR_SYNTAX };
            }
            lpush(_cmds[4]);
        }
        else if (_cmds[3] == "rpush") {
            if (_cmds.size() < 5) {
                LOG_ERR(ERR_SYNTAX);
                return { -1, ERR_SYNTAX };
            }
            rpush(_cmds[4]);
        }
        else {
            LOG_ERR(ERR_SYNTAX);
            return { -1, ERR_SYNTAX };
        }
    }
    else {
        LOG_ERR(ERR_OPT);
        return { -1, ERR_OPT };
    }
    return { 0, OPT_SUCC };
}

void list_t::lpush(const std::string & _s) {
    _content.push_front(_s);
}

void list_t::rpush(const std::string & _s) {
    _content.push_back(_s);
}

void list_t::lpop() {
    if (!_content.empty()) _content.pop_front();
}

void list_t::rpop() {
    if (!_content.empty()) _content.pop_back();
}

std::string list_t::lget() {
    return _content.empty() ? "" : _content.front();
}

std::string list_t::rget() {
    return _content.empty() ? "" : _content.back();
}


}

